﻿using System.Linq;

namespace Basmus.Values
{
    public class ValuesService : IValuesService<object>
    {
        private readonly IContextService _contextService;
        private readonly IBindingBuilder _bindingBuilder;
        private readonly IGetterSetterBuilder _getterSetterBuilder;

        public ValuesService(IContextService contextService, IBindingBuilder bindingBuilder, IGetterSetterBuilder getterSetterBuilder)
        {
            _contextService = contextService;
            _bindingBuilder = bindingBuilder;
            _getterSetterBuilder = getterSetterBuilder;
        }

        public void SetValues(ModelContext modelContext, object target, IValuesProvider<object> valuesProvider)
        {
            var valuesContexts = _contextService.GetValuesContexts(modelContext);
            foreach (var valuesContext in valuesContexts)
            {
                var values = valuesProvider.GetValues(valuesContext.Name);
                var elements = values == null ? null : values.ToArray();
                var getterSetter = _getterSetterBuilder.Build(valuesContext);
                if (getterSetter != null)
                {
                    var container = _bindingBuilder
                        .Build(valuesContext)
                        .GetContainer(elements);
                    getterSetter.Set(target, container);
                }
            }
        }

        public IValuesProvider<object> GetValues(ModelContext modelContext, object target)
        {
            var valuesProvider = new ValuesProvider<object>();
            var valueContexts = _contextService
                .GetValuesContexts(modelContext);
            foreach (var valuesContext in valueContexts)
            {
                var getterSetter = _getterSetterBuilder.Build(valuesContext);
                if (getterSetter != null)
                {
                    var container = getterSetter.Get(target);
                    var elements = _bindingBuilder
                        .Build(valuesContext)
                        .GetElements(container);
                    valuesProvider.Set(valuesContext.Name, elements);
                }
            }
            return valuesProvider;
        }
    }
}